namespace LightBox.Hosting
{
	using System;
	using System.Web;
	using System.Web.Configuration;
	using System.Web.Hosting;
	using System.Web.Security;

	using Providers;
	using Configuration;

	/// <summary>
	/// Default Image virtual path provider for LightBox.NET
	/// </summary>
	public class ImageVirtualPathProvider : VirtualPathProvider
	{
		private ImageProviderCollection providers;
		private static object objLock = new object();

		/// <summary>
		/// Public default constructor
		/// </summary>
		public ImageVirtualPathProvider() : base() { }

		/// <summary>
		/// Registers this virtual provider with the web hosting engine.
		/// </summary>
		public static void AppInitialize()
		{
			ImageVirtualPathProvider provider = new ImageVirtualPathProvider();
			HostingEnvironment.RegisterVirtualPathProvider(provider);
		}

		/// <summary>
		/// Checks whether the specified virtual path is supported.
		/// </summary>
		/// <param name="virtualPath"></param>
		/// <returns></returns>
		public override bool FileExists(string virtualPath)
		{
			if (IsValidVirtualPath(virtualPath))
			{
				return true;
			}

			return base.FileExists(virtualPath);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="virtualPath"></param>
		/// <returns></returns>
		private bool IsValidVirtualPath(string virtualPath)
		{
			return (FindImageProvider(virtualPath) != null);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="virtualPath"></param>
		/// <returns></returns>
		private ImageProvider FindImageProvider(string virtualPath)
		{
			foreach (ImageProvider provider in this.providers)
			{
				IImageUrlHandler urlHandler = provider as IImageUrlHandler;

				if (urlHandler != null)
				{
					if (urlHandler.IsUrlSupported(virtualPath))
					{
						return provider;
					}
				}
			}

			return null;
		}

		public override VirtualFile GetFile(string virtualPath)
		{
			ImageProvider provider = FindImageProvider(virtualPath);

			if (provider != null)
			{
				return new ImageVirtualFile(virtualPath, provider);
			}

			return base.GetFile(virtualPath);
		}

		/// <summary>
		/// Initializes the common structure for the providers.
		/// </summary>
		protected override void Initialize()
		{
			lock (objLock)
			{
				base.Initialize();

				LightBoxSection section = WebConfigurationManager.GetSection(LightBoxSection.SectionName) as LightBoxSection;

				if (section.Providers != null)
				{
					providers = new ImageProviderCollection();
					ProvidersHelper.InstantiateProviders(section.Providers,
						providers, typeof(ImageProvider));
				}
			}
		}
	}
}